import {
  ProFormInstance,
  ProFormRadio,
  ProFormSelect,
  ProFormText,
  ProFormTextArea,
  StepsForm
} from '@ant-design/pro-components';
import {list} from '@/services/data-media-api'
import React, {MutableRefObject, useRef, useState} from 'react';
import {BaseOptionType} from "rc-select/es/Select";
import {Button, Form, message, Modal} from "antd";
import ColumnsMap from "@/pages/DataMediaPair/MediaPair/components/ColumnsMap";
import {create, createColumnPair, findColumnPair, queryColumnGroup,createColumnGroup, update} from '@/services/data-media-pair-api'
import ColumnGroup from "@/pages/DataMediaPair/MediaPair/components/ColumnGroup";
import {NamePath} from "rc-field-form/es/interface";


export type CreateOrUpdateFormProps = {
  onCancel: (flag?: boolean, formVals?: API.DataMediaPair) => void;
  onFinish?: () => Promise<void>;
  pipelineId?: number;
  channelId?: number;
  updateModalOpen: boolean;
  values?: Partial<API.DataMediaPair>;
  title?: string;
};

/**
 * @en-US Update node
 * @zh-CN 更新节点
 *
 * @param fields
 */
const handleUpdate = async (fields: API.DataMediaPair) => {
  const hide = message.loading('更新中');
  try {
    const res = await update(fields);
    hide();

    if (res) {
      message.success('更新成功');
      return true;
    }
    return false;
  } catch (error) {
    hide();
    return false;
  }
};


const CreateOrUpdateForm: React.FC<CreateOrUpdateFormProps> = (props) => {

  const [optionsType, setOptionsType] = useState<BaseOptionType[]>();
  const [schemas, setSchemas] = useState<string[]>([]);
  const formRef = useRef<ProFormInstance>();
  const formMapRef = useRef<MutableRefObject<ProFormInstance | undefined>[]>([]);
  const [current, setCurrent] = useState<number>(0);
  const [dataMediaPairId, setDataMediaPairId] = useState<number>();
  const [columnMapInitialValue, setColumnMapInitialValue] = useState<API.ColumnPairDTO>();
  const [columnGroupInitialValue, setColumnGroupInitialValue] = useState<API.ColumnGroupDTO>();
  const {onFinish} = props;

  const fetchOptionType = async () => {
    const data = await list({size: 100, page: 1})
      .then(res => res["data"])
      .then(d => d.map((s: API.DataMedia<any>) => ({label: (s.namespace + '.' + s.name), value: s.id})))
    setOptionsType(data);
    return data;
  }


  const getSchema = (key: number) => {
    return optionsType?.findLast(o => o.value === key)?.label;
  }

  const handleAdd = async (fields: API.DataMediaPair) => {
    const hide = message.loading('正在添加');
    try {
      const res = await create({...fields});
      hide();
      if (res) {
        setDataMediaPairId(res);
        message.success('添加成功');
        return true;
      }
      return false;
    } catch (error) {
      hide();
      return false;
    }
  };


  const createColumnsPair = async (values: { columnsMapping: API.ColumnPairDTO, [param: string]: any }) => {

    const hide = message.loading('正在提交....');
    try {
      const {columnsMapping, ...value} = values;
      const res = await createColumnPair({...columnsMapping, ...value});
      hide();
      if (res) {
        message.success('提交成功');
        return true;
      }
      return false;
    } catch (error) {
      hide();
      return false;
    }
  }

  const createColumnsGroup = async (values: { columnsGroupMapping: API.CreateColumnGroupDTO, [param: string]: any }) => {

    const hide = message.loading('正在提交....');
    try {
      const {columnsGroupMapping, ...value} = values;
      const res = await createColumnGroup({...columnsGroupMapping, ...value});
      hide();
      if (res) {
        message.success('提交成功');
        return true;
      }
      return false;
    } catch (error) {
      hide();
      return false;
    }
  }
  const getFieldValue = (key: NamePath) => {
    return formMapRef
      ?.current
      ?.findLast(f => f?.current?.getFieldFormatValue!(key))
      ?.current?.getFieldFormatValue!(key);
  }
  const onStepChange = async (step: number) => {
    setCurrent(step);
    if (step === 0) {
      return;
    }

    const id = props?.values?.id || dataMediaPairId
    const sourceId = props?.values?.source?.id || getFieldValue(['source', 'id']);
    const targetId = props?.values?.target?.id || getFieldValue(['target', 'id']);
    if (!(id && sourceId && targetId)) {
      return;
    }
    // 步骤二初始化
    if (step === 1) {
      try {
        const pair: API.ColumnPairDTO = await findColumnPair({
          dataMediaPairId: id,
          sourceMediaId: sourceId,
          targetMediaId: targetId,
        });
        setColumnMapInitialValue(pair);
      } catch (e) {
        setColumnMapInitialValue({})
      }
    }
    if (step === 2) {
      try {
        const pair: API.ColumnGroupDTO = await queryColumnGroup({
          dataMediaPairId: id,
          sourceMediaId: sourceId,
          targetMediaId: targetId,
        });
        setColumnGroupInitialValue(pair);
      } catch (e) {
        setColumnGroupInitialValue({})
      }
    }
  }


  return (
    <StepsForm
      formRef={formRef}
      formMapRef={formMapRef}
      current={current}
      onCurrentChange={onStepChange}
      submitter={{
        render: (props) => {
          if (props.step === 0) {
            return ([
                <Button type="primary" key="step1" onClick={() => props.onSubmit?.()}>
                  下一步
                </Button>,
                <Button
                  type="primary"
                  key="step1Commit"
                  onClick={async () => {
                    const {errorFields} = await props?.form?.validateFields();
                    if (errorFields) {
                      return;
                    }
                    props.onSubmit?.();
                    setDataMediaPairId(undefined);
                    setTimeout( async () => { await onFinish?.();},1000);
                  }}
                >
                  提交
                </Button>
              ]
            );
          }

          if (props.step === 1) {
            return [
              <Button key="pre" onClick={() => props.onPre?.()}>
                上一步
              </Button>,
              <Button
                type="primary"
                key="step2"
                onClick={() => props.onSubmit?.()}
              >
                下一步
              </Button>,
              <Button
                type="primary"
                key="step2Commit"
                onClick={async () => {
                  const {errorFields} = await props?.form?.validateFields();
                  if (errorFields) {
                    return;
                  }
                  props.onSubmit?.();
                  setDataMediaPairId(undefined);
                  await onFinish?.();
                }}
              >
                提交
              </Button>,
            ];
          }

          return [
            <Button key="gotoTwo" onClick={() => props.onPre?.()}>
              上一步
            </Button>,
            <Button
              type="primary"
              key="goToTree"
              onClick={async () => {
                const {errorFields} = await props?.form?.validateFields();
                if (errorFields) {
                  return;
                }
                props.onSubmit?.();
                setDataMediaPairId(undefined);
                setCurrent(0);
                await onFinish?.();
              }}
            >
              提交
            </Button>,
          ];
        },
      }}
      stepsFormRender={(dom, submitter) => {
        return (
          <Modal
            title="配置映射"
            width={800}
            onCancel={() => {
              props.onCancel();
              setDataMediaPairId(undefined);
              setCurrent(0);
            }}
            open={props.updateModalOpen}
            footer={submitter}
            destroyOnClose={true}
          >
            {dom}
          </Modal>
        );
      }}
    >
      <StepsForm.StepForm
        name="configTableMappings"
        title="映射表配置"
        layout={"horizontal"}
        labelCol={{span: 8}}
        onFinish={async (value) => {
          setSchemas([getSchema(getFieldValue(['source', 'id'])), getSchema(getFieldValue(['target', 'id']))]);
          if (props?.values?.id || dataMediaPairId) {
            return handleUpdate({...value, id: (props?.values?.id || dataMediaPairId)});
          } else {
            return handleAdd(value);
          }
        }}
      >
        <ProFormText initialValue={props?.values?.id} hidden={true} name='id'/>
        <ProFormText initialValue={props?.pipelineId} hidden={true} name='pipelineId'/>
        <ProFormSelect
          label="源数据表"
          width="md"
          initialValue={props.values?.source?.id}
          name={['source', 'id']}
          request={fetchOptionType}
        />
        <ProFormSelect
          initialValue={props.values?.target?.id}
          label="目标数据表"
          width="md"
          name={['target', 'id']}
          options={optionsType}
        />
        <ProFormText
          initialValue={props.values?.pushWeight}
          rules={[
            {
              required: true,
              message: '权重不能为空',
            },
          ]}
          width="md"
          label="权重"
          name="pushWeight"
        />
        <ProFormRadio.Group
          initialValue={props.values?.columnPairMode || 'INCLUDE'}
          options={[
            {
              label: 'include',
              value: 'INCLUDE'
            },
            {
              label: 'exclude',
              value: 'EXCLUDE'
            }
          ]}
          width="md"
          label="视图模式"
          name="columnPairMode"
        />
        <ProFormSelect
          label="EventProcessor类型"
          width="sm"
          initialValue={props.values?.filterData?.extensionDataType || 'CLAZZ'}
          options={[
            {
              value: 'CLAZZ',
              label: 'CLAZZ'
            },
            {
              value: 'SOURCE',
              label: 'SOURCE'
            },
          ]}
          name={['filterData', 'extensionDataType']}
        />
        <ProFormTextArea
          initialValue={props.values?.filterData?.sourceText}
          name={['filterData', 'sourceText']}
          label={'EventProcessor文本'}
        />
        <ProFormSelect
          label="FileResolver类型"
          width="sm"
          initialValue={props.values?.resolverData?.extensionDataType || 'SOURCE'}
          options={[
            {
              value: 'CLAZZ',
              label: 'CLAZZ'
            },
            {
              value: 'SOURCE',
              label: 'SOURCE'
            },
          ]}
          name={['resolverData', 'extensionDataType']}
        />
        <ProFormTextArea
          initialValue={props.values?.resolverData?.sourceText}
          name={['resolverData', 'sourceText']}
          label={'FileResolver文本'}
        />
      </StepsForm.StepForm>

      <StepsForm.StepForm
        name="configColumnsMappings"
        onFinish={createColumnsPair}
        title="列映射配置">
        <ProFormText hidden={true} name="channelId" initialValue={props?.channelId}/>
        <ProFormText hidden={true} name="pipelineId" initialValue={props?.pipelineId}/>
        <ProFormText hidden={true} name="dataMediaPairId" initialValue={props?.values?.id || dataMediaPairId}/>
        <Form.Item name={"columnsMapping"}>
          <ColumnsMap initialValue={columnMapInitialValue} sourceSchema={schemas[0]} targetSchema={schemas[1]}/>
        </Form.Item>
      </StepsForm.StepForm>

      <StepsForm.StepForm
        name="configColumnsGroupMappings"
        onFinish={createColumnsGroup}
        title="列映射组配置">
        <ProFormText hidden={true} name="channelId" initialValue={props?.channelId}/>
        <ProFormText hidden={true} name="pipelineId" initialValue={props?.pipelineId}/>
        <ProFormText hidden={true} name="dataMediaPairId" initialValue={props?.values?.id || dataMediaPairId}/>
        <Form.Item name={"columnsGroupMapping"}>
          <ColumnGroup initialValue={columnGroupInitialValue}/>
        </Form.Item>
      </StepsForm.StepForm>
    </StepsForm>
  );
};

export default CreateOrUpdateForm;
